package general.data_model.text_data;

import general.data_model.ClusterTeaser;
import general.data_model.Data;
import general.data_model.DataTeaser;
import general.data_model.Source;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 * this is a class that represents all the textual data which should be processed and stored in the Database
 * you are encouraged to extend this class for you own purposes which will still maintain all its functionality
 * @author Andrej Gajduk
 *
 */
public class TextData extends Data {
	
	/**
	 * the description of the main content for this text
	 */
	private static final String main_content_description = "main";
	
	/**
	 * the entire contents of the text document this Data represents
	 * some text documents have some information tagged and this should be somehow imported in this contents
	 * e.g
	 * 
	 * In a web page you would normally see a table filled with the following info
	 *  Purpose: Study
	 *	Level: 	 Master,  PhD
	 *	Quota: 	Decided by the community
	 *	Application deadline: 	Summer 
	 *
	 * because this info can differ highly from web page to web page, even within the same problem it's practically not good
	 * to have separate attributes for all such data, instead we should put them in a map file where the keys tell us what the value represents
	 * like an Application deadline and the value to be Summer.
	 * This way if we want the plain text data in order to lets say to compare the data from two different web pages in which the one gives some of the info separated whilst the other one does not
	 * which is a very common case, we should only fetch the values and concat them together
	 * and when we are comparing, classifying two Data objects that both have a value for some attribute like Application deadline we can easily access those values 
	 */
	private Content contents;
	
	public TextData () {
	}
	
	/**
	 * initializes the content and the classifier information as empty, and sets all other fields fields required in the Data class,
	 * you can always set the classifier information and the contents later via the addXXXX methods
	 * @param title
	 * @param source
	 * @param accessed_a
	 */
	public TextData ( String title  , Source source , Date accessed_at , Date valid_until ) {
		super(title,source,accessed_at,valid_until);
		this.contents = new Content(title);
	}
	
	/**
	 * initializes the content as empty and sets all other fields
	 * @param title
	 * @param source
	 * @param accessed_at
	 * @param classifier_information
	 */
	public TextData ( String title, Source source , Date accessed_at , Date valid_until , Map<String,String> classifier_information  , ClusterTeaser cluster_teaser ) {
		super(title,source,accessed_at,valid_until,classifier_information,cluster_teaser);
		this.contents = new Content(title);
	}
	
	/**
	 * sets all the fields appropriately
	 * you can always update the classifier information and the contents later via the addXXXX methods
	 * @param title
	 * @param source
	 * @param accessed_at
	 * @param classifier_information
	 * @param contents
	 */
	public TextData ( String title , Source source , Date accessed_at  , Date valid_until , Map<String,String> classifier_information , ClusterTeaser cluster_teaser , Content contents) {
		super(title,source,accessed_at,valid_until,classifier_information,cluster_teaser);
		this.contents = contents;
	}
	
	/**
	 * initializes the classifier information to an empty map, and sets all other fields
     * you can always set the classifier information and the contents later via the addXXXX methods
	 * @param title
	 * @param source
	 * @param accessed_at
	 * @param contents
	 */
	public TextData ( String title  , Source source , Date accessed_at  , Date valid_until , Content contents) {
		super(title,source,accessed_at,valid_until);
		this.contents = contents;
	}
	
	/**
	 * adds a new key:value pairs of description:content to the map, if a field with that key (description) already exists it is replaced
	 * @param classifier_name
	 * @param class_attribute_value
	 */
	public void addContentsField ( Content content ) {
		this.contents.addContent(content);
	}
	
	/**
	 * removes an existing key:value pairs of description:content to the map, as specified by the key
	 * if that key does not exist it does nothing
	 * @param description - the description which defines the key:value pair we wish to remove
	 */
	public void removeContentsField ( String description ) {
		this.contents.removeContentByDescription(description);
	}
	
	/**
	 * get the field from the contents that corresponds to the given key (content description)
	 * @param classifier_name
	 * @return the value for that content description or an empty string if such key does not occur in the map
	 */
	public Content getContentsField ( String description ) {
		return contents.getContentForDescription(description);
	}

	/**
	 * @return the contents
	 */
	public Content getContents() {
		return contents;
	}

	/**
	 * @param contents the contents to set
	 */
	public void setContents(Content contents) {
		this.contents = contents;
	}

	/**
	 * gets the main content of this text data, it is the most relevant and (obemna) information retrieved considering this text file
	 * this is same as getContentsField(TextData.main_content_description)
	 * @return the main content 
	 */
	public Content getMainContent ( ) {
		return contents.getContentForDescription(main_content_description);
	}
	
	/**
	 * sets the main content of this text data, it is the most relevant and (obemna) information retrieved considering this text file
	 * this is same as addContentsField(TextData.main_content_description)
	 * @param content - the content to set
	 */
	public void setMainContent ( Content content ) {
		content.setDescription(main_content_description);
		contents.addContent(content);
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return super.toString()+contents.toString(true);
	}
	
}
